package com.game.basic;


import java.math.BigDecimal;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;

import com.game.config.Config;
import com.game.state.BasicState;
import com.game.utils.ImageTool;
import com.game.utils.LoadingThread;
import com.game.utils.PhoneInfo;
import com.game.utils.SpeedUtil;
import com.game.utils.Tools;

public abstract class BasicView_Buff extends SurfaceView implements Callback,Runnable{
	public SurfaceHolder holder;
	public Canvas canvas;
	//用于保存loading的状态
	public byte loadingStep=-1;
	//标识否循环loading
	public boolean loopLoading=true;
	//默认的最大loading,用于循环显示loading
	public byte maxLoadingStep=4;
	//loading 的刷新速度
	public byte loadingSpeed = 20;
	//刷新屏幕的时间
	public long screenFlushTime;
	//用于保存计数器
	public int[] counter;
	//loading计数器
	public final byte COUNTER_LOADING=0;
	//用于标识loading
	public boolean loading;
	//用于标识刷新
	public boolean drawing;
	//用于标识暂停
	public boolean pause=false;
	//当前绘制线程,此线程会变化,但只有唯一一条
	public Thread drawThread;
	//标识按下
	public boolean pressing=false;
	//游戏状态
	public BasicState gameState;
	//上下文Activity
	public BasicActivity context;
	
	Bitmap screenContent ;//把所有内容绘制到这张图片上
	Canvas gameCanvas ;//用来绘制内容图片的画布
	Paint paint ;
	
	//关闭按钮
	public Bitmap closeButton=ImageTool.getBitMapForceScale("exit.png");
	
	public float[] closePosts;
	{
		if(closeButton!=null){
			closePosts= new float[]{
					PhoneInfo.endScreenX-closeButton.getWidth(),
					PhoneInfo.endScreenY-closeButton.getHeight(),
					PhoneInfo.endScreenX,
					PhoneInfo.endScreenY
			};
		}
	}
	
	
	/**
	 * view的构造方法,初始化基本设置**/
	public BasicView_Buff(BasicActivity context) {
		super(context);
		Log.i("infos", "构造view: "+this.getClass());
		this.context=context;
		
		this.setKeepScreenOn(true);//设置背景常亮  
		super.setFocusable(true);	//确保我们的View能获得输入焦点  
		super.setFocusableInTouchMode(true); //确保能接收到触屏事件   
//		super.setLongClickable(true);//设置可以长按
		
		holder=getHolder();
		holder.addCallback(this);
		
		screenFlushTime=Config.SCREEN_FLUSH_TIME;//初始化draw刷新频率
		
		counter=new int[1];//计时器,默认只有loading计时器所以大小为1;
		
		//初始化这张图片
		screenContent = Bitmap.createBitmap(PhoneInfo.screenWidth_def,PhoneInfo.screenHeight_def,Bitmap.Config.ARGB_8888);
		//初始化画布
		gameCanvas = new Canvas(screenContent);
		
		paint= Tools.createNewPaint();
		
		//初始化View完成
		//自动调用 surfaceCreated方法
	}
	
	
	/**
	 * 实例化view时会执行此方法,启动初始化线程和绘制线程
	 * 重设drawing为true
	 * 重设firstStart为false
	 * 
	 * view destory后恢复会执行此方法,重新建一个绘制线程
	 * 重设drawing为true*/
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		Log.i("infos",  this.getClass()+" surfaceCreated");
		if(!drawing){/*不是绘画*/
			
			drawing=true;/*转为绘画状态*/
			
			drawThread=new Thread(this);/*启动draw线程,详细见run*/
			
			drawThread.start();
		}
	}
	
	/**
	 * view销毁时执行此方法,
	 * 重设drawing为false
	 * 重设pause为true*/
	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		Log.i("infos", this.getClass()+" surfaceDestroyed");
	}
	
	/**
	 * 更改*/
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
		Log.i("infos",  this.getClass()+" surfaceChanged");
	}
	
	/**
	 * 绘画线程启动时调用draw方法,循环标识为drawing*/
	@Override
	public void run() {
		/*drawing状态会在surfaceCreated ,paint中变更*/
		while(drawing){
			long startTime=System.currentTimeMillis();//获得开始draw的毫秒数
			
			draw();
			
			long delayTime=System.currentTimeMillis()-startTime;//获得结束draw的毫秒数,计算时间差
			
			if(delayTime<screenFlushTime)//时间差小于最少刷新频率,阻塞时间差
				DelayTime(screenFlushTime-delayTime);
		}
	}
	
	
	/**
	 * 此方法在draw线程中被执行,绘制屏幕
	 * 主要封装holder.lockCanvas()和holder.unlockCanvasAndPost(canvas)操作
	 * 实际绘制方法是各个paint方法*/
	public void draw(){
		/** 构建后缓冲区和后缓冲画笔 **/
		canvas = holder.lockCanvas();
		try{
			//统一处理各种暂停和加载
			if(canvas!=null){
				//抗锯齿
				canvas.setDrawFilter(new PaintFlagsDrawFilter(0,Paint.FILTER_BITMAP_FLAG));
				//绘制一层黑色  在黑色层上重新绘制
				canvas.drawColor(Color.BLACK);
		/****************************以下内容受屏幕分辨率影响********************************/				
				//pause会在activity切换中改变
				if(pause){
					paintPausing(gameCanvas);//绘制暂停画面
				}
				//loading会在state切换中改变
				else if(loading){
					paintLoading(gameCanvas);//绘制loading画面
				}
				else{
					if(gameState!=null){
						/*state初始化完成后*/
						if(!initState()){
							//调用游戏状态的draw方法
							gameState.draw(gameCanvas);
							//给予view扩展,此方法绘制出来的将出现在屏幕最上方
							paint(gameCanvas);
						}
					}
				}
		/****************************处理缩放***********************************************/
				//处理屏幕边界
				canvas.save();
				canvas.clipRect(ImageTool.getScreenRect());
				
				
				if(PhoneInfo.scale){
					//处理不同分辨率的缩放
					canvas.translate(PhoneInfo.startScreenX,PhoneInfo.startScreenY);
					if(Config.FULL_SCREEN){
						canvas.scale(PhoneInfo.scaleX,PhoneInfo.scaleY);
					}else{
						canvas.scale(PhoneInfo.scaleLonely,PhoneInfo.scaleLonely);
					}
				}
				long t = System.currentTimeMillis();
				//绘制内容
				canvas.drawBitmap(screenContent,0,0, paint);
				Log.i("infos", "view使用时间====="+(System.currentTimeMillis()-t));
				
				
//				long t = System.currentTimeMillis();
//				if(PhoneInfo.scale){
//					Matrix scaleMx=null;
//					scaleMx = new Matrix();
//					if(Config.FULL_SCREEN){
//						scaleMx.postScale(PhoneInfo.scaleX,PhoneInfo.scaleY);
//					}else{
//						scaleMx.postScale(PhoneInfo.scaleLonely,PhoneInfo.scaleLonely);
//					}
//					canvas.drawBitmap(screenContent, scaleMx, paint);
//					
//				}else{
//					canvas.drawBitmap(screenContent,0,0, paint);
//				}
//				Log.i("infos", "view使用时间====="+(System.currentTimeMillis()-t));
				
				
		/****************************还原缩放***********************************************/		
				//屏幕边界 还原
				canvas.restore();
				
		/*****************************以下内容不受缩放影响********************************************/
				if(Config.DRAW_FPS){
					drawFps(canvas);//绘制fps
				}
				//关闭按钮通用的关闭按钮
				if(closeButton!=null){
					ImageTool.drawImgBottomRight(canvas, closeButton);
				}
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if(canvas!=null)
				holder.unlockCanvasAndPost(canvas);
		}
	}
	
	/**
	 * 默认的paintPausing方法
	 * 子类中可重写此方法实现自定义的绘制暂停的方法*/
	public void paintPausing(Canvas canvas){
		drawPause(canvas);
	}
	
	/**
	 * 默认的paintLoading方法
	 * 子类中可重写此方法实现自定义的loading方式
	 * 此loading是循环loading,每maxLoadingStep次循环一次*/
	public void paintLoading(Canvas canvas) {
		//使用计时器画loading
		if(loopLoading&&countTime(COUNTER_LOADING,SpeedUtil.getCountSpeed(loadingSpeed))){
			loadingStep++;
		}
		if(loopLoading&&loadingStep>maxLoadingStep){
			loadingStep=0;
		}
		drawLoading(canvas, loadingStep);
	}
	
	
	/**
	 * 切换游戏状态*/
	public void changeState(BasicState state){
		//保存之前的状态
		BasicState oldState=gameState;
		//变为新的状态
		gameState=state;
		if(oldState!=null){
			//调用destory方法
			oldState.destory();
			oldState=null;
			System.gc();
		}
	}
	
	/**
	 * 触摸关闭按钮
	 * @param x
	 * @param y
	 */
	public void touchExit(float x,float y){
		if(closeButton!=null){
			if(isTouchInRegion(x, y, closePosts)){
				context.destoryApp();
			}
		}
	}
	
	int pointerId=0;
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
//		Log.i("infos", "触摸view");
//		int pointerCount = event.getPointerCount();
//		Log.i("infos", "pointerid"+event.getPointerId(0));
//		Log.i("infos", ""+pointerCount);
		//重新封装触摸点,放大为默认屏幕大小的值
		
		//触摸关闭按钮
		touchExit(event.getX(),event.getY());
		float x= event.getX();
		float y = event.getY();
		if(PhoneInfo.scale){
			x=Config.FULL_SCREEN?x/PhoneInfo.scaleX:(x-PhoneInfo.startScreenX)/PhoneInfo.scaleLonely;
			y=Config.FULL_SCREEN?y/PhoneInfo.scaleY:(y-PhoneInfo.startScreenY)/PhoneInfo.scaleLonely;
			event.setLocation(x, y);
		}
		//防止多触摸
		if(pointerId!=event.getPointerId(0)){
			pressing=false;
		}
		
		int action=event.getAction();
		switch(action){
			//按下
			case MotionEvent.ACTION_DOWN:{
//				Log.i("infos", "ACTION_DOWN"+action);
				//标识按下
				pressing=true;
				if(pause){
					pause=false;
					restartLogicThread();
				}
				break;
			}
			//提起
			case MotionEvent.ACTION_UP:{
//				Log.i("infos", "ACTION_UP"+action);
				pressing=false;
				break;	
			}
		}
		
		//loading状态不做任何处理
		if(loading){
			return true;
		}
		
	/***************************************************以下在loading状态不可响应****************************/
		if(gameState!=null){
			//把按键事件交给状态处理
		    gameState.onTouchEvent(event);
		}
		
		//让事件线程休眠 减少触发次数
		synchronized(this){
           try{
               this.wait(50);     
            }catch(InterruptedException e){
             e.printStackTrace();
           }         
        }
		return true;
	}
	
	/**
	 * 暂停后重启逻辑线程*/
	public void restartLogicThread(){
		if(gameState!=null){
			//非实例化的时候
			if(!initState()){
				/*开始逻辑处理,一条逻辑处理线程对应一条draw线程*/
				gameState.startLogic();
			}
		}
	}
	
	/**
	 * 新建进程
	 * 初始化state
	 */
	public boolean initState(){
		//已有一个状态在初始化
		if(loading) 
			return true;
		if(gameState.initIng){
			loading=true;//标识开始初始化资源
			new LoadingThread(gameState).start();/*开启线程初始化资源*/
			return true;
		}
		return false;
		
	}
	
	/**
	 * 提供给真实类绘制的方法
	 * 这里绘制的是view的最顶层*/
	public abstract void paint(Canvas canvas);

	
	/**
	 * 休眠方法*/
	public void DelayTime( long time ){
		try{
			Thread.sleep( time );
		}catch( Exception ex ){
			ex.printStackTrace();
		}
	}
	
	/**
	 * 计时器方法
	 * @param index 计时器的下标,如默认的loading计时器为0
	 * @param time 时长,超过此时长重设计时器
	 * 真正的时间大于等于(time*screenFlushTime)*/
	public boolean countTime(int index,float max){
		counter[index] = (int) ((counter[index] + 1) % max);
		return counter[index]==0;
//		counter[index]=counter[index]+1;
//		if(counter[index]>time){
//			counter[index]=0;
//			return true;
//		}
//		return false;
		
    }
	
	
	
	//用于调试
	private float FPS=0;
	private long startT=0;
	private int fpsCount = 0;
	private int FPS_SAMPLE = 20 ;//帧数采样值
	private String memoryInfo="N/A";//程序信息
	public void drawFps(Canvas canvas){
		Paint p=new Paint();
//		Typeface fontFace = Typeface.createFromAsset(ImageTool.getAssetManager(),"font/ROCKEB.TTF");
//		p.setTypeface(fontFace);
		fpsCount++;
		if(fpsCount == FPS_SAMPLE){	//帧数满采样值
			fpsCount = 0;
			long nowTime = System.currentTimeMillis();
			long span = nowTime - startT;		
			startT = nowTime;
			FPS = (1000f/span)*FPS_SAMPLE;//计算帧速率  根据采样值需要的时间计算1秒的帧数
			
//			memoryInfo=SystemInfoUtil.instance.getCurrentAPPMemoryUsage();
		}
		p.setColor(Color.BLUE);
		p.setTextSize(25);
		
		//格式化fps
		String sFPS="";
		BigDecimal bd = new BigDecimal(FPS);  
		sFPS = sFPS+ bd.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();  
		//绘制fps
		canvas.drawText("FPS:"+sFPS, 21,21 , p);
//		//绘制内存使用
//		canvas.drawText(memoryInfo,200,21 , p);
		//绘制图片信息
		canvas.drawText(ImageTool.getImageCondition(),400,21 , p);
		
	}
		
	
	
	/**
	 * 默认的绘制loading*/
	public static void drawLoading(Canvas canvas,int step){
		Paint paint=new Paint();
		paint.setColor(Color.WHITE);//白字
//		paint.setTextAlign(Paint.Align.CENTER); 中心绘制文字
		canvas.drawColor(Color.BLACK);//黑底
		StringBuffer loadingText=new StringBuffer("Loading");
		float textWidth=paint.measureText(loadingText.toString());
		for(int i=0;i<step;i++){
			loadingText.append(" .");	
		}
		canvas.drawText(loadingText.toString(), PhoneInfo.screenWidthHalf_def-textWidth/2, PhoneInfo.screenHeightHalf_def, paint);
	}
	
	/**
	 * 默认的绘制暂停*/
	public static void drawPause(Canvas canvas){
		Paint paint=new Paint();
		paint.setColor(Color.WHITE);//白字
		canvas.drawColor(Color.BLACK);//黑底
		String text="触摸屏幕继续";
		float textWidth=paint.measureText(text);
		canvas.drawText(text, PhoneInfo.screenWidthHalf_def-textWidth/2, PhoneInfo.screenHeightHalf_def, paint);
	}
	
	/**
	 * 判断touch是否在区域内*/
	public static boolean isTouchInRegionWH(float touchX,float touchY,float[] poses){
		return isTouchInRegion(touchX,touchY,poses[0],poses[1],poses[0]+poses[2],poses[1]+poses[3]);
	}
	
	/**
	 * 判断touch是否在区域内*/
	public static boolean isTouchInRegion(float touchX,float touchY,float[] poses){
		return isTouchInRegion(touchX,touchY,poses[0],poses[1],poses[2],poses[3]);
	}
	
	/**
	 * 判断touch是否在区域内
	 * @param touchX
	 * @param touchY
	 * @param startX
	 * @param startY
	 * @param endX
	 * @param endY
	 * */
	public static boolean isTouchInRegion(float touchX,float touchY,float startX,float startY,float endX, float endY){
		if( touchX > startX && touchX < endX ){
			if( touchY > startY && touchY < endY ){
				return true;
			}
		}
		return false;
	}
	
	/**
	 * 判断点击屏幕左边还是右边
	 * 左:true; 右: false
	 * @param x
	 * @param start_y
	 * @return
	 */
	public static boolean touchLeftRight(float x){
		if(x<=PhoneInfo.screenWidthHalf){
			return true;
		}else{
			return false;
		}
	}
	
}